<script setup>
import { VXETable } from "vxe-table"
import { upload } from '@/api/public'
import { download } from '@/utils'
import Paste from './Paste'

const emit = defineEmits(['update:modelValue'])
const props = defineProps({
  modelValue: { type: [String, Array] },
  title: { type: String, default: '文件' },
  types: { type: Array, default: () => (['png', 'jpg', 'jpeg']) },
  edit: Boolean, // 是否开启名称编辑功能
  disabled: Boolean,
  limit: { type: [String, Number], default: () => '' },
  multiple: Boolean,
  required: Boolean, // 是否必填，仅展示样式，校验用el-form-item包一层来处理，也可以使用插槽 title 来自定义标题
  inline: { type: [Boolean, Number], default: true }, // 列表是否在一行展示，默认一行展示三个，传入数字可控制一行展示数量
  params: { type: Object, default: () => ({}) }, // 上传时的额外参数
})

const pasteRef = ref()

const list = computed({
  get() {
    return (Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue]).filter(Boolean)
  },
  set(val) {
    emit('update:modelValue', val)
  }
})

// 上传文件
const loadings = reactive({})
const readFile = async (fileds) => {
  const { files } = (fileds || await VXETable.readFile({ multiple: props.multiple, types: props.types }))
  const { params, limit } = props
  for (const file of files) {
    const param = new FormData()
    param.append('file', file)
    for (const key in params) {
      param.append(key, params[key])
    }
    try {
      loadings.upload = true
      const res = await upload(param)
      let { file_preview } = res.data[0]
      const name = file.name.replace(file.lastModified, '')
      const obj = props.edit ? {file_url: file_preview, file_name: name} : file_preview
      if (+limit === 1) {
        list.value = [obj]
      } else {
        list.value.push(obj)
        list.value = list.value
      }
      loadings.upload = false
    } catch (error) {
      console.log(error)
      loadings.upload = false
    }
  }
}

const remove = i => {
  list.value.splice(i, 1)
  list.value = list.value
}

const viewImageRef = ref()
const handleClick = (d) => {
  viewImageRef?.value.open(d)
}

const getName = (d) => d?.slice(d.lastIndexOf('/') + 1)
</script>

<template>
  <div class="v-upload-file">
    <div class="v-upload-file-header">
      <div class="v-upload-file-title">
        <span v-if="required" class="v-upload-file-required">*</span>
        <slot name="title">{{ title }}</slot>
      </div>
      <template v-if="!disabled">
        <el-divider direction="vertical" />
        <el-button link size="small" type="primary" :loading="loadings.upload" :disabled="disabled" @click="() => pasteRef.open()">
          <el-icon v-if="!loadings.upload" style="font-size: 16px;">
            <CirclePlus />
          </el-icon>上传附件
        </el-button>
        <span class="v-upload-file-tip">
          <slot />
        </span>
      </template>
    </div>
    <div class="v-upload-file-list" :style="`grid-template-columns: repeat(${typeof inline === 'number' ? inline : 3}, minmax(0, 1fr))`">
      <div link v-for="(d, i) in list" :key="i" class="v-upload-file-list-item">
        <template v-if="edit">
          <div style="width: calc(100% - 100px);">
            <el-input v-model="d.file_name" placeholder="请输入" class="w-full" />
          </div>
          <div style="display: flex;flex: 0 0 90px;max-height: 28px!important;">
            <span class="w-8">
              <VText value="查看" type="button" @click="handleClick(d.file_url)" />
            </span>
            <span class="w-8 ml-1">
              <VText value="下载" type="button" @click="download(d.file_url)" />
            </span>
            <el-button type="danger" link icon="Delete" :disabled="disabled" class="ml-1" @click="remove(i)"></el-button>
          </div>
        </template>
        <template v-else>
          <div style="width: calc(100% - 100px);">
            <VText :value="getName(d)" type="button" style="max-height: 28px!important;" @click="handleClick(d)" />
          </div>
          <div style="display: flex;flex: 0 0 90px;max-height: 28px!important;">
            <span class="w-8">
              <VText value="下载" type="button" @click="download(d)" />
            </span>
            <el-button type="danger" link icon="Delete" :disabled="disabled" class="ml-1" @click="remove(i)"></el-button>
          </div>
        </template>
      </div>
      <small v-if="!list.length" class="text-gray-400">尚未添加附件</small>
    </div>
  </div>
  <ViewImage ref="viewImageRef" />
  <Paste ref="pasteRef" :accept="types.map(d => `.${d}`).join(',')" @success="readFile" />
</template>

<style lang="scss">
.v-upload-file {
  width: 100%;

  &-header {
    display: flex;
    align-items: center;
  }

  &-title {
    margin-right: 3px;
    font-weight: bold;
  }

  &-required {
    color: var(--el-color-danger);
    margin-right: 4px;
  }

  &-tip {
    margin-left: 10px;
    color: #999;
  }

  &-list {
    display: grid;
    gap: 3px;

    &-item {
      width: 100%;
      display: flex;
      align-items: center;
      column-gap: 1rem;
      overflow: hidden;
    }
  }
}
</style>